/**
 *****************************************************************************
 * DESC ：. 
 * Author : Junwei Zhang 
 * CREATEDATE ：2012-8-11 
 * MODIFYLIST ：       	Name 			 Date 			Reason/Contents
 * 				------------------------------------------------------ 
 * 				 	Junwei Zhang     2012-8-11		Created.
 ****************************************************************************
 **/
package com.me.client.plugins.TicTacToe;

import java.lang.reflect.Method;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import com.me.client.JTalkClientCommandInterface;
import com.me.client.JTalkClientPlugInInterface;
import com.me.client.JTalkClientPluginConnector;

/**
 * 
 * <br/>
 * 上午9:54:46 2012-8-11
 * 
 * @Author <a href="mailto:mestudying@sina.com">Junwei Zhang</a><br/>
 **/
public class TicTacToe implements JTalkClientPlugInInterface, JTalkClientCommandInterface {

	private static final int ENEMY_REMOTE = 0;
	/** 游戏图标. */
	private ImageIcon myIcon = null;
	/** 游戏与客户端的连接. */
	private JTalkClientPluginConnector myConnector = null;
	/** 游戏设置面板. */
	private TTTSettings mySettings = null;
	/** 游戏是否已经开始. */
	private boolean gameIsActive = false;
	/** 游戏面板. */
	private TTTWindow myWindow = null;
	/** 游戏对手的名字. */
	public String enemyName = "";
	public String myName = "";
	public int winCounterUser = 0;
	public int winCounterEnemy = 0;

	public TicTacToe() {
		this.myWindow = new TTTWindow(this);
		this.mySettings = new TTTSettings(this);
		this.myIcon = new ImageIcon(getClass().getResource("ttticon.png"));
	}

	@Override
	public boolean setParentObject(JTalkClientPluginConnector connector) {
		this.myConnector = connector;
		this.myConnector.registerForCommandResponse(this);
		this.myName = this.myConnector.getUserName();
		System.out.println("+ (TicTacToe) Ok, parent object initialized: " + connector);
		return true;
	}

	@Override
	public String getName() {
		return "Tic-Tac-Toe";
	}

	@Override
	public Icon getIcon() {
		return this.myIcon;
	}

	@Override
	public String getDescription() {
		return "The player who succeeds in placing three respective marks in a horizontal, "
				+ "vertical or diagonal row wins the game.";
	}

	@Override
	public Method[] getCommandMethods() {
		Method[] methods = new Method[4];
		try {
			methods[0] = this.getClass().getDeclaredMethod("inviteForGame", new Class[] { String.class });
			methods[1] = this.getClass().getDeclaredMethod("turn", new Class[] { String.class });
			methods[2] = this.getClass().getDeclaredMethod("restartGame");
			methods[3] = this.getClass().getDeclaredMethod("cancelRunningGame");
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return methods;
	}

	/**
	 * 邀请对方玩游戏.
	 * 
	 * @param userName
	 *            被邀请人名称.
	 * @return
	 */
	public String inviteForGame(String userName) {
		System.out.println("----> inviteForGame()");
		if (this.gameIsActive) {
			return "NOTOK: Another Game is running";
		}
		this.winCounterEnemy = 0;
		this.winCounterUser = 0;
		int retVal = JOptionPane.showConfirmDialog(null, userName
				+ " wants to play\nTic-Tac-Toe with you.\nDo you agree?", "Want to play?", JOptionPane.YES_NO_OPTION);
		if (retVal == JOptionPane.YES_OPTION) {
			this.enemyName = userName;
			this.myWindow.startNewGame(false, 2, ENEMY_REMOTE, -1, this.enemyName);
			this.myWindow.setVisible(true);
			this.gameIsActive = true;
			return "OK";
		} else {
			return "NOTOK: Rejected";
		}
	}

	/**
	 * 获取对方下的棋.
	 * 
	 * @param index
	 * @return
	 */
	public String turn(String index) {
		System.out.println("----> turn()");
		if (!this.gameIsActive) {
			return "NOTOK: Invite first";
		}
		if (this.myWindow.setExternalAction(Integer.parseInt(index))) {
			return "OK";
		} else {
			return "NOTOK: Unknown error occured";
		}
	}

	/**
	 * 重新开始游戏.
	 * 
	 * @return
	 */
	public String restartGame() {
		System.out.println("----> restartGame()");
		this.myWindow.startNewGame(false, 1, ENEMY_REMOTE, -1, this.enemyName);
		this.myWindow.setVisible(true);
		this.gameIsActive = true;
		return "OK";
	}

	/**
	 * 取消正在进行的游戏.
	 * 
	 * @return
	 */
	public String cancelRunningGame() {
		System.out.println("----> cancelRunningGame()");
		this.gameIsActive = false;
		this.myWindow.setVisible(false);
		return "OK";
	}

	@Override
	public JFrame getMainFrame() {
		// TODO Auto-generated method stub
		if (this.myConnector != null) {
			this.mySettings.setUserList(this.myConnector.getOnlineUsers());
		}
		if (!this.gameIsActive) {
			return this.mySettings;
		} else {
			return this.myWindow;
		}
	}

	public static void main(String[] args) {
		new TicTacToe().getMainFrame().setVisible(true);
	}

	/**
	 * 开始游戏.
	 * 
	 * @param restart
	 */
	public void startNewGame(boolean restart) {
		if (restart && this.myName.length() > 0 && this.enemyName.length() > 0) { // 重新开始游戏.
			System.out.println("----> Restarting the game with the same settings");
			this.gameIsActive = false;
			this.myConnector.sendMessage("jtplugin.TicTacToe::restartGame()", this.enemyName, "command", "",
					"msgTTTRestart");
			return;
		}
		if (this.mySettings.getGameType() == ENEMY_REMOTE) { // remote user
			this.enemyName = this.mySettings.getSelectedUser();
			this.gameIsActive = false;
			this.myConnector.sendMessage("jtplugin.TicTacToe::inviteForGame(" + this.myName + ")", this.enemyName,
					"command", "", "msgTTTInvite");
		} else { // artificial intelligence
			this.myWindow.startNewGame(true, 1, this.mySettings.getGameType(), this.mySettings.getSelectedAI(), "AI");
			this.enemyName = "AI";
			this.myWindow.setVisible(true);
			this.gameIsActive = true;
		}
	}

	/**
	 * 若和在线用户玩游戏,通知用户.
	 * 
	 * @param field
	 */
	public void setTurn(int field) {
		if (this.mySettings.getGameType() == ENEMY_REMOTE) {
			// Remote Game
			this.myConnector.sendMessage("jtplugin.TicTacToe::turn(" + field + ")", this.enemyName, "command", "",
					"msgTTTTurn");
		}
	}

	/**
	 * 结束当前游戏.
	 */
	public void endCurrentGame() {
		if (this.mySettings.getGameType() == ENEMY_REMOTE) {
			// Remote Game
			this.myConnector.sendMessage("jtplugin.TicTacToe::cancelRunningGame()", this.enemyName, "command", "",
					"msgTTTCancel");
			this.gameIsActive = false;
		} else {
			// Local Game
			this.myWindow.startNewGame(true, 1, this.mySettings.getGameType(), this.mySettings.getSelectedAI(), "AI");
			this.myWindow.setVisible(false);
			this.gameIsActive = false;
		}
	}

	@Override
	public boolean setCommandAnswer(String messageID, String sender, String content) {
		// TODO Auto-generated method stub
		if ("msgTTTInvite".equals(messageID)) {
			if ("OK".equals(content)) {
				if (this.gameIsActive) {
					return false;
				}
				System.out.println("----> Get OK for INVITE");
				this.winCounterEnemy = 0;
				this.winCounterUser = 0;
				this.myWindow.setVisible(true);
				this.myWindow.startNewGame(true, 1, this.mySettings.getGameType(), this.mySettings.getSelectedAI(),
						this.mySettings.getSelectedUser());
				this.gameIsActive = true;
				return true;
			} else {
				System.out.println("----> *** Got NOTOK for invite.");
				JOptionPane.showMessageDialog(this.myWindow, "Can't start a game.\nThe message was:\n" + content,
						"Can't start a game.", JOptionPane.INFORMATION_MESSAGE);
			}
			return false;
		} else if ("msgTTTRestart".equals(messageID)) {
			if ("OK".equals(content)) {
				if (this.gameIsActive) {
					return false;
				}
				System.out.println("----> Get OK for RESTART");
				this.myWindow.setVisible(true);
				this.myWindow.startNewGame(true, 1, this.mySettings.getGameType(), this.mySettings.getSelectedAI(),
						this.mySettings.getSelectedUser());
				this.gameIsActive = true;
				return true;
			} else {
				System.out.println("----> *** Get NOTOK for invite.");
				JOptionPane.showMessageDialog(this.myWindow, "Can't restart a game.\nThe message was:\n" + content,
						"Can't start a game.", JOptionPane.INFORMATION_MESSAGE);
				return false;
			}
		}else if("msgTTTCancel".equals(messageID)){
			if ("OK".equals(content)) {
				System.out.println("----> Got OK for CANCEL - cancel too.");
				this.gameIsActive = false;
				this.myWindow.setVisible(false);
			}
		}
		return false;
	}

	@Override
	public void upload() {
		this.myConnector.deRegisterForCommandResponse(this);
		this.myConnector = null;
	}

}
